package com.hand.pp.aspect;/**
 * @author Estelle@앙수청
 * @date 2019/7/18 11:27
 */

import com.alibaba.fastjson.JSON;
import com.hand.pp.annotation.ACCESS;
import com.hand.pp.annotation.PermissionAnnotation;
import com.hand.pp.annotation.PrivilegeAnnotation;
import com.hand.pp.interceptor.ErrorMsg;
import com.hand.pp.service.UserService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.PrintWriter;
import java.util.List;
import java.util.Map;

/**
 *  @author Estelle@앙수청
 *  @date 2019/7/18 11:27
 */
@Aspect
@Component
public class PrivilegeAspect {

    @Autowired
    private UserService service;

    @Pointcut("@annotation(com.hand.pp.annotation.PermissionAnnotation)")
    public void permissionPointCut(){}

    @Around("permissionPointCut()&&"+"@annotation(permissionAnnotation)")
    public Object PerssionAround(ProceedingJoinPoint pjp, PermissionAnnotation permissionAnnotation) throws Throwable {
        Object o = null;
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

        boolean check = permissionAnnotation.value();
        if (!check){
            o = pjp.proceed();
        }else {
            if (validatePermission(request)){
                o = pjp.proceed();
            }else {
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/json");
                response.setStatus(HttpStatus.FORBIDDEN.value());
                ErrorMsg errorMsg = new ErrorMsg("NO_ACCESS", "当前用户权限不足");
                String msg = JSON.toJSONString(errorMsg);
                PrintWriter writer = response.getWriter();
                writer.print(msg);
                writer.close();
            }
        }
        return o;
    }

    private Boolean validatePermission(HttpServletRequest request){
        boolean result = false;
        String id = request.getHeader("id");
        if (!StringUtils.isEmpty(id)){
            List<Map<String, String>> maps = service.queryUserPermission(Long.valueOf(id));
            String uri = request.getRequestURI();
            String method = request.getMethod();
            AntPathMatcher matcher = new AntPathMatcher();
            for (Map<String, String> map : maps) {
                if (matcher.match(map.get("path"),uri) && matcher.match(map.get("path"), method)){
                    result = true;
                    break;
                }
            }
        }
        return result;
    }
}
